* VIRTUAL HARD DRIVE VIA SERIAL PORT TO PC
* (C)2001 TERENCE J. BOLDT

* PRODOS GLOBAL PAGE VALUES
DEV2S1   EQU   $BF14      ;POINTER FOR SLOT 2 DRIVE 1 DRIVER
DEVCNT   EQU   $BF31      ;DEVICE COUNT -1
DEVLST   EQU   $BF32      ;DEVICE LIST

* PRODOS ZERO PAGE VALUES
COMMAND  EQU   $42        ;PRODOS COMMAND
UNIT     EQU   $43        ;PRODOS SLOT/DRIVE
BUFLO    EQU   $44        ;LOW BUFFER
BUFHI    EQU   $45        ;HI BUFFER
BLKLO    EQU   $46        ;LOW BLOCK
BLKHI    EQU   $47        ;HI BLOCK

* PRODOS ERROR CODES
IOERR    EQU   $27
NODEV    EQU   $28
WPERR    EQU   $2B

* GS SPECIFIC SERIAL PORT
SSCINIT  EQU   $C245
SSCREAD  EQU   $C246
SSCWRITE EQU   $C247
SSCSTAT  EQU   $C248

* ROM LOCATIONS
RESETC8  EQU   $CFFF

         ORG   $1800


* INITIALISE DRIVER
INIT     EQU   *
* ADD POINTER TO DRIVER
         LDA   #<DRIVER
         STA   DEV2S1
         LDA   #>DRIVER
         STA   DEV2S1+1
* ADD TO DEVICE LIST
         INC   DEVCNT
         LDY   DEVCNT
         LDA   #$20       ;SLOT 2 DRIVE 1
         STA   DEVLST,Y

         RTS

* DRIVER CODE
DRIVER   EQU   *
* CHECK THAT WE HAVE THE RIGHT DRIVE
         LDA   UNIT
         CMP   #$20       ;SLOT 2 DRIVE 1
         BEQ   DOCMD      ;YEP, DO COMMAND
         SEC              ;NOPE, FAIL
         LDA   #NODEV
         RTS

* CHECK WHICH COMMAND IS REQUESTED
DOCMD    EQU   *
         LDA   COMMAND
         BNE   NOTSTAT    ;0 IS STATUS
         JMP   GETSTAT
NOTSTAT  CMP   #$01
         BNE   NOREAD     ;1 IS READ
         JMP   READBLK
NOREAD   CMP   #$02
         BNE   NOWRITE    ;2 IS WRITE
         JMP   WRITEBLK
NOWRITE  LDA   #$00       ; CLEAR ERROR
         CLC
         RTS


* STATUS
GETSTAT  EQU   *
         LDA   #$00
         LDX   #$FF
         LDY   #$FF
         CLC
         RTS

* READ
READBLK  EQU   *
* SEND COMMAND TO PC
         LDA   RESETC8    ; RESET C8 PAGE
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCINIT    ; INIT SERIAL CARD
         LDA   #$01       ; SEND ^A Z TO SERIAL DRIVER TO ZAP CONTROL CHARS
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         LDA   #$5A
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         LDA   #$01       ; READ COMMAND
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         LDA   BLKLO
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         LDA   BLKHI
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         LDA   #$00       ; CHECKSUM
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
* READ ECHO'D COMMAND AND VERIFY
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCREAD
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCREAD
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCREAD
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCREAD
* READ BLOCK AND VERIFY
         LDX   #$00
RDBKLOOP LDY   #$00
RDLOOP   EQU   *
         PHX
         PHY
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCREAD
         PLY
         PLX
         STA   (BUFLO),Y
         INY
         BNE   RDLOOP

         INC   BUFHI
         INX
         CPX   #$02
         BNE   RDBKLOOP

         DEC   BUFHI

         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCREAD

         LDA   #$00
         CLC
         RTS

* WRITE
WRITEBLK EQU   *
* SEND COMMAND TO PC
         LDA   RESETC8
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCINIT    ; INIT SERIAL CARD
         LDA   #$01       ; SEND ^A Z TO SERIAL DRIVER TO ZAP CONTROL CHARS
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         LDA   #$5A
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         LDA   #$02       ; WRITE COMMAND
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         LDA   BLKLO
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         LDA   BLKHI
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         LDA   #$00       ; CHECKSUM
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE

* WRITE BLOCK AND CHECKSUM
         LDX   #$00
WRBKLOOP LDY   #$00
WRLOOP   EQU   *
         PHX
         PHY
         LDA   (BUFLO),Y
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE
         PLY
         PLX
         INY
         BNE   WRLOOP

         INC   BUFHI
         INX
         CPX   #$02
         BNE   WRBKLOOP

         DEC   BUFHI

         LDA   #$00
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCWRITE

* READ ECHO'D COMMAND AND VERIFY
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCREAD
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCREAD
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCREAD
         LDX   #$C2       ; SET X AND Y FOR SSC CALLS
         LDY   #$20
         JSR   SSCREAD

         LDA   #$00
         CLC
         RTS
